/*
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package hextd.message;

import hextd.message.MessageFactory.NetworkMessage;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MessageSettings implements Message {

	public static enum settingKey {

		ladderGame,
		openGame,
		pause,
		publicGame,
		ready,
		selectedMap,
		mapMD5,
		version
	}
	public NetworkMessage type = NetworkMessage.Settings;
	public static char separator = ';';
	public static String RegExp = "SETTINGS ([-0-9]+) (" + separator + "([^" + separator + "]+" + separator + ")+)";
	public static Pattern MessagePattern = Pattern.compile(MessageSettings.RegExp);
	//
	private String message;
	private int senderId = -2;
	private HashMap<settingKey, String> settings;

	public static String formatMessage(int userId, HashMap<settingKey, String> settings) {
		String message = "SETTINGS " + userId + " " + separator + "";
		for (Entry<settingKey, String> setting : settings.entrySet()) {
			try {
				message += URLEncoder.encode(setting.getKey().toString(), "UTF-8") + "=" + URLEncoder.encode(setting.getValue(), "UTF-8") + separator;
			} catch (UnsupportedEncodingException ex) {
				Logger.getLogger(MessageSettings.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
		return message;
	}

	public static String formatMessageSingle(int userId, settingKey key, String value) {
		String message = "SETTINGS " + userId + " " + separator + "";
		try {
			message += URLEncoder.encode(key.toString(), "UTF-8") + "=" + URLEncoder.encode(value, "UTF-8") + separator;
		} catch (UnsupportedEncodingException ex) {
			Logger.getLogger(MessageSettings.class.getName()).log(Level.SEVERE, null, ex);
		}
		return message;
	}

	public MessageSettings() {
	}

	private MessageSettings(String message) {
		this.message = message;
		Matcher matcher = MessageSettings.MessagePattern.matcher(message);
		if (matcher.matches()) {
			try {
				senderId = new Integer(matcher.group(1)).intValue();
			} catch (NumberFormatException e) {
				System.err.println("MessageSay: invalid id in: " + matcher.group(1));
			}

			settings = new HashMap<settingKey, String>();
			String settingList = matcher.group(2);
			settingList = settingList.substring(1, settingList.length() - 1);
			String[] settingsArray = settingList.split("" + separator);
			for (int i = 0; i < settingsArray.length; i++) {
				String[] settingArray = settingsArray[i].split("=");
				if (settingArray.length == 2) {
					try {
						String key = URLDecoder.decode(settingArray[0], "UTF-8");
						String val = URLDecoder.decode(settingArray[1], "UTF-8");
						settings.put(settingKey.valueOf(key), val);
					} catch (UnsupportedEncodingException ex) {
						Logger.getLogger(MessageSettings.class.getName()).log(Level.SEVERE, null, ex);
					}
				}

			}

		}
	}

	public HashMap<settingKey, String> getSettings() {
		return settings;
	}

	@Override
	public String getMessage() {
		return this.message;
	}

	@Override
	public Message initFromString(String message) {
		return new MessageSettings(message);
	}

	/**
	 * Get the userId of the sending user.
	 * @return Get the userId of the sending user.
	 */
	@Override
	public int getSenderId() {
		return this.senderId;
	}

	/**
	 * Set the userId of the sending user.
	 * @param userId
	 */
	@Override
	public void setSenderId(int userId) {
		senderId = userId;
		message = formatMessage(userId, settings);
	}

	@Override
	public Pattern getPattern() {
		return MessageSettings.MessagePattern;
	}

	@Override
	public NetworkMessage getType() {
		return this.type;
	}
}
